<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 
    vue2中的数据响应式，主要靠defineProperty。当状态发生了变化，肯定会触发set操作，进而触发re-render生成新的虚拟DOM，新旧的虚拟DOM会进行diff运算，找到差异，交给Vue背后更新队列去执行循环更新。说白了就是更新界面。

    上面set操作完后，引起的一系列的过程都是异步。说白了，更新模板的过程是异步的。有一个api，叫nextTick。
    nextTick表示下一个更新单元（更新周期）。在更新队列中每一个更新任务叫更新单元。

    作用：改变data，引发set操作，如果想获取最新的dom，需要使用nextTick。
   -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>
</head>

<body>
  <div id="app">
    <h2>{{name}}</h2>
    <h2 v-text="num" id="h1"></h2>
    <button @click="add">+1</button>
    <hr>
    <h1 v-html="msg"></h1>
    <hr>
    <!-- <h1 v-text="info.user.child[0].age"></h1> -->
    <h1 v-text="info.user.child[0]"></h1>
    <button @click="change">change</button>
  </div>
  <script>

    let vm = new Vue({
      el: "#app",
      data() {
        return {
          name: "码路",
          num: 1,
          msg: "",
          // info: {
          //   user: {
          //     child: [
          //       {
          //         name: "ml",
          //         age: 18
          //       }
          //     ]
          //   }
          // },
          info: {
            user: {
              child: [
                18
              ]
            }
          }
        }
      },
      mounted() {
        // 模拟ajax
        setTimeout(() => {
          let res = `<div><a id="a" href="">我是一个孤独的div</a></div>`;
          this.msg = res;

          // 这样写肯定是不行。
          // document.getElementById("a").style.color = "red";

          this.$nextTick(() => {
            document.getElementById("a").style.color = "red";
          })
        }, 200)
      },
      methods: {
        add() {
          // 数据变了，要刷新模板，这个刷新过程是异步的。
          // 操作数据的代码是同步，背后刷新模板的逻辑是异步的。
          // 数据变了，产生新的虚拟DOM，新旧虚拟DOM会进行diff算法，找到差异，差异也叫脏节点。
          // 找到脏节点后，交给vue的更新队列，去异步的更新节点
          // vue和react都是数据驱动
          // vue: MVVM   声明式编程
          // react：setState   函数式编程
          this.num++

          // 获取的并不是最新DOM
          // nextTick， next是下一个的意思  Tick是记录的意思
          // 每一次更新，可能有非常多的更新任务，每一个更新任务叫一个更新单元。
          // nextTick表示下一个更新单元（下一下更新周期）
          // let res = document.getElementById("h1").innerHTML;
          // console.log(res);


          // nextTick和updated有什么区别？
          // 答：updated表示整个模板重新渲染完毕后才执行，是指整个界面。
          //    nextTick表示下一个更新周期
          this.$nextTick(() => {
            let res = document.getElementById("h1").innerHTML;
            console.log(res);
          })
        },
        change() {
          // this.info.user.child[0].age++

          // 当data中有数据是一个数组，数组中放了基本数据类型
          // 通过索引去改变数据，模板是不会刷新，这个数据并不是响应式。
          this.info.user.child[0]++

          // 直接操作数组的length，也不是响应式的。
          // this.info.user.child.length = 0;

          // 你觉得的vue的响应式系统有什么缺陷？
          // 答：组件嵌套的非常深，data的数据结构也非常深，可能会导致响应式系统失效。
          // 如何解决？
          //   A）$forceUpdate();  强制更新
          //   B）对数据进行深copy
          //     this.info.user.child[0].age++  
          //     this.info = JSON.parse(JSON.stringfy(this.info))

          this.$forceUpdate();
        }
      },
    });
  </script>
</body>

</html>